const fs = require('fs')
const util = require('util')



/**
 *
	let readFile = promisify(fs.readFile);
	readFile('./name.txt', 'utf-8')
		.then(res => readFile(res, 'utf-8'))
		.then(res => readFile(res, 'utf-8'))
		.then(res => console.log(res))
 *
 */
 function callbackPromiseV5() {
 	var files = ['./resource/1.html','./resource/2.html','./resource/3.html']
 	var i = 0, content = '';
 	var readFile =  util.promisify(fs.readFile)

	// 内部包装了2个函数
	function buildContent (data, idx) {
		content += data 
		return readFile(files[idx], 'utf-8')
	}

	function co(promise, i, onFinished) {
		// 进入函数之后 先 ++i
		if(++i >= files.length) {
			return promise
		}
		// 将相同的代码再抽取一次， buildContent 每次都是返回一个promise
		var p = promise.then(data => buildContent(data, i))
		return co(p, i, onFinished)
	}

	var p = readFile(files[i], 'utf-8'); // 获取到promise对象进行链式调用
	co(p, i).then(data => {
		console.log('最后一次的链式调用:', data)
		console.log('-----------------------')
		console.log(content)
	})
}


// 迭代器的方案
function * callbackPromiseV6() { 
	var files = ['./resource/1.html','./resource/2.html','./resource/3.html']
	var i = 0, content = '';
	var readFile =  util.promisify(fs.readFile)
	
	let data1 = yield  readFile(files[i++], 'utf-8')
	content += data1
	
	let data2 = yield  readFile(files[i++], 'utf-8')
	content += data2

	let data3 = yield  readFile(files[i++], 'utf-8')
	content += data3

	return content
}



/*

var it = callbackPromiseV6();
var {value: promise, done} = it.next();
promise.then(value => {
	var {value: promise, done}  = it.next(value)
	promise.then(value => {
		var {value: promise, done}  = it.next(value)
		promise.then(value => {
			var {value: promise, done}  = it.next(value)
			console.log(done)
			setTimeout(()=> {
				console.log(promise)
			},1000)
		})
	})
})
*/


/**
 * 通过回调函数 onFinished 获取最后的 callbackPromiseV6最终的返回值
 * @param  {[type]} it         [description]
 * @param  {[type]} onFinished [description]
 * @param  {[type]} value      [description]
 * @return {[type]}            [description]
 */
 function coV1 (it, onFinished, value) {
 	let {value:p, done} = it.next(value)
 	if(done) {
 		onFinished && onFinished(p, done, value)
 		return 
 	}
 	p.then(value => {
 		coV1(it, onFinished, value)
 	})
 }

// 可行的版本
// coV1(callbackPromiseV6(), function(value, done, lastVal) {
// 	console.log(value)
// })


/**
 * coV2 内部包一个函数 对coV1的简化
 * @param  {[type]} it         [description]
 * @param  {[type]} onFinished [description]
 * @return {[type]}            [description]
 */
 function coV2(it, onFinished) {
	// 保存所有 yield 返回的结果
	let results = [] 
	let next = function(data) {
		results.push(data);
		let {value, done} = it.next(data)
		if(done) {
			// console.log(results)
			return  onFinished(value);
		}
		value.then(data => {
			next(data)
		})
	}
	next()
}


// coV2(callbackPromiseV6(), function(value) {
// 	console.log(value)
// })



/**
 * 将coV2 改为Promise版本
 * @param  {[type]} it         [description]
 * @param  {[type]} onFinished [description]
 * @return {[type]}            [description]
 */
 function coV3(it) {
 	it || (it = callbackPromiseV6())
	// 保存所有 yield 返回的结果
	let results = []

	return new Promise((resovle, reject) => {
		let next = function(data) {
			results.push(data);
			let {value, done} = it.next(data)
			if(done) {
				return resovle(value);
			}
			value.then(data => {
				next(data)
			}, reject)
		}
		next()
	})
}


// coV3().then(value => {
// 	console.log(value)
// })


// tj/co 模块，包装一个生成器generator函数
// let tjCo = require('co')
// tjCo(callbackPromiseV6()).then(data => {
// 	console.log(data)
// })

function coV4(it) {
	it || (it = callbackPromiseV6())
	// 保存所有 yield 返回的结果
	let results = []
	var i = 0;

	// 用Promise 包裹异步的任务
	return new Promise((resolve, reject) => {

		wrap(it.next())

		// 将next()的数据当做参数传递过来
		function wrap(res) {
			// console.log(`iaaa = ${++i}`)

			if(res.done)  {
				// console.log(res)
				// console.log(results)
				return resolve(res.value);
			}
			res.value.then(data => {
				let yieldRet  = it.next(data);
				results.push(data)
				// console.log(`i = ${++i}`)
				wrap(yieldRet)
			})
		}
	})

}
var a = coV4() ;
a.then(value => {
	console.log('-----------------------\n')
	console.log(value)
})
// setTimeout(() => {
// 	console.log(a)
// })






/**
 * async + await 方式
 * @yield {[type]} [description]
 */
 async function  callbackPromiseV7() { 
 	var files = ['./resource/1.html','./resource/2.html','./resource/3.html']
 	var i = 0, content = '';
 	var readFile =  util.promisify(fs.readFile)

 	let data1 = await  readFile(files[i++], 'utf-8')
 	content += data1

 	let data2 = await  readFile(files[i++], 'utf-8')
 	content += data2

 	let data3 = await  readFile(files[i++], 'utf-8')
 	content += data3

 	return content
 }

// callbackPromiseV7().then(data => {
// 	console.log(data)
// })